/**
* <copyright>
*
* Copyright (c) 2004-2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
*
* </copyright>
*
* $Id: MapToEcoreActionDelegate.java,v 1.8 2008/05/04 10:59:02 emerks Exp $
*/
package org.eclipse.emf.ecore.xcore.ui;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.codegen.ecore.genmodel.GenBase;
import org.eclipse.emf.codegen.ecore.genmodel.GenClassifier;
import org.eclipse.emf.codegen.ecore.genmodel.GenModel;
import org.eclipse.emf.codegen.ecore.genmodel.GenModelFactory;
import org.eclipse.emf.codegen.ecore.genmodel.GenModelPackage;
import org.eclipse.emf.codegen.ecore.genmodel.GenPackage;
import org.eclipse.emf.codegen.util.ImportManager;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EGenericType;
import org.eclipse.emf.ecore.EModelElement;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.plugin.EcorePlugin;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.xcore.XImportDirective;
import org.eclipse.emf.ecore.xcore.XPackage;
import org.eclipse.emf.ecore.xcore.XcoreFactory;
import org.eclipse.emf.ecore.xcore.ui.internal.XcoreActivator;
import org.eclipse.emf.ecore.xcore.util.EcoreXcoreBuilder;
import org.eclipse.emf.ecore.xcore.util.XcoreGenModelInitializer;
import org.eclipse.emf.ecore.xcore.util.XcoreGenmodelBuilder;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.ActionDelegate;
import org.eclipse.ui.actions.WorkspaceModifyOperation;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.part.ISetSelectionTarget;
import org.eclipse.xtext.resource.SaveOptions;
import org.eclipse.xtext.resource.XtextResourceSet;
import com.google.inject.Inject;
import com.google.inject.Provider;
/**
*
*/
public class ConvertToXcoreActionDelegate extends ActionDelegate
{
@Inject
Provider<EcoreXcoreBuilder> ecoreXcoreBuilderProvider;
@Inject
XcoreGenmodelBuilder genModelBuilder;
@Inject
XcoreGenModelInitializer genModelInitializer;
protected EPackage getInputEPackage(IStructuredSelection structuredSelection)
{
Object element = structuredSelection.getFirstElement();
if (element instanceof IFile)
{
IFile file = (IFile)element;
XtextResourceSet resourceSet = new XtextResourceSet();
IProject project = file.getProject();
resourceSet.setClasspathURIContext(JavaCore.create(project));
resourceSet.getURIConverter().getURIMap().putAll(EcorePlugin.computePlatformURIMap());
if ("ecore".equals(file.getFullPath().getFileExtension()))
{
return
(EPackage)EcoreUtil.getObjectByType
(resourceSet.getResource(URI.createPlatformResourceURI(file.getFullPath().toString(), true), true).getContents(),
EcorePackage.Literals.EPACKAGE);
}
else if ("genmodel".equals(file.getFullPath().getFileExtension()))
{
GenModel genModel =
(GenModel)EcoreUtil.getObjectByType
(resourceSet.getResource(URI.createPlatformResourceURI(file.getFullPath().toString(), true), true).getContents(),
GenModelPackage.Literals.GEN_MODEL);
if (genModel.getGenPackages().size() == 1)
{
return genModel.getGenPackages().get(0).getEcorePackage();
}
}
}
return null;
}
protected IFile getFile(Resource resource)
{
URI uri = resource.getURI();
uri = resource.getResourceSet().getURIConverter().normalize(uri);
String platformResourceString = uri.toPlatformString(true);
return platformResourceString != null ?
ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(platformResourceString)) :
null;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
*/
@Override
public void run(IAction action)
{
final IWorkbenchWindow workbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
final EPackage inputEPackage = getInputEPackage((IStructuredSelection)workbenchWindow.getSelectionService().getSelection());
final Resource inputResource = inputEPackage.eResource();
URI outputResourceURI = inputResource.getURI().trimFileExtension().appendFileExtension("xcore");
final Resource outputResource = inputResource.getResourceSet().createResource(outputResourceURI);
ProgressMonitorDialog dialog = new ProgressMonitorDialog(workbenchWindow.getShell());
try
{
dialog.run(false, true,
new WorkspaceModifyOperation()
{
@Override
protected void execute(IProgressMonitor progressMonitor)
{
try
{
progressMonitor.beginTask("", 1);
Resource genModelResource = inputResource.getResourceSet().getResources().get(0);
GenModel inputGenModel = null;
if (genModelResource != inputResource)
{
inputGenModel = (GenModel)genModelResource.getContents().get(0);
inputGenModel.reconcile();
final GenModel genModel = GenModelFactory.eINSTANCE.createGenModel();
genModel.initialize(Collections.singleton(inputEPackage));
genModelResource.getContents().add(genModel);
genModelInitializer.initialize(genModel);
new Object()
{
void visit(GenBase genBase1, GenBase genBase2)
{
if (genBase1.eClass() == genBase2.eClass())
{
for (EAttribute eAttribute : genBase1.eClass().getEAllAttributes())
{
// TODO
if (!eAttribute.isMany() && genBase1.eIsSet(eAttribute))
{
Object value1 = genBase1.eGet(eAttribute);
Object value2 = genBase2.eGet(eAttribute);
if (value1 == null ? value2 != null : !value1.equals(value2))
{
EModelElement eModelElement = genBase2.getEcoreModelElement();
if (eModelElement == null)
{
eModelElement = genModel.getGenPackages().get(0).getEcorePackage();
}
EcoreUtil.setAnnotation
(eModelElement,
GenModelPackage.eNS_URI,
eAttribute.getName(),
EcoreUtil.convertToString(eAttribute.getEAttributeType(), value1));
}
for (Iterator<EObject> i = genBase1.eContents().iterator(), j = genBase2.eContents().iterator(); i.hasNext() && j.hasNext(); )
{
EObject content1 = i.next();
EObject content2 = j.next();
if (content1 instanceof GenBase && content2 instanceof GenBase)
{
visit((GenBase)content1, (GenBase)content2);
}
}
}
}
}
}
}.visit(inputGenModel, genModel);
}
else
{
// TODO what about no GenModel?
// We'd want to create one and use that...
}
EcoreXcoreBuilder ecoreXcoreBuilder = ecoreXcoreBuilderProvider.get();
ecoreXcoreBuilder.initialize(inputGenModel);
XPackage xPackage = ecoreXcoreBuilder.getXPackage(inputEPackage);
outputResource.getContents().add(xPackage);
outputResource.getContents().add(inputGenModel);
outputResource.getContents().add(inputEPackage);
GenPackage ecoreGenPackage = inputGenModel.getEcoreGenPackage();
if (ecoreGenPackage != null)
{
outputResource.getContents().add(ecoreGenPackage.getGenModel());
}
GenPackage xmlTypeGenPackage = inputGenModel.getXMLTypeGenPackage();
if (xmlTypeGenPackage != null)
{
outputResource.getContents().add(xmlTypeGenPackage.getGenModel());
}
GenPackage xmlNamespaceGenPackage = inputGenModel.getXMLNamespaceGenPackage();
if (xmlNamespaceGenPackage != null)
{
outputResource.getContents().add(xmlNamespaceGenPackage.getGenModel());
}
ecoreXcoreBuilder.link();
genModelBuilder.buildMap(inputGenModel);
ImportManager importManager =
new ImportManager(inputGenModel.getGenPackages().get(0).getInterfacePackageName())
{
@Override
protected boolean shouldImport(String packageName, String shortName, String importName)
{
return true;
}
};
for (Iterator<EObject> i = inputEPackage.eAllContents(); i.hasNext(); )
{
EObject eObject = i.next();
if (eObject instanceof EGenericType)
{
EGenericType eGenericType = (EGenericType)eObject;
EClassifier eClassifier = eGenericType.getEClassifier();
if (eClassifier != null)
{
GenClassifier genClassifier = inputGenModel.findGenClassifier(eClassifier);
String qualifiedName = genClassifier.getGenPackage().getInterfacePackageName() + "." + eClassifier.getName();
importManager.addImport(qualifiedName);
}
}
}
for (String qualifiedName : importManager.getImports())
{
XImportDirective xImportDirective = XcoreFactory.eINSTANCE.createXImportDirective();
xImportDirective.setImportedNamespace(qualifiedName);
xPackage.getImportDirectives().add(xImportDirective);
}
try
{
Map<Object, Object> options = new HashMap<Object, Object>();
SaveOptions.newBuilder().format().noValidation().getOptions().addTo(options);
outputResource.save(options);
IFile file = getFile(outputResource);
IWorkbenchPage workbenchPage = workbenchWindow.getActivePage();
final IWorkbenchPart activePart = workbenchPage.getActivePart();
if (activePart instanceof ISetSelectionTarget)
{
final ISelection targetSelection = new StructuredSelection(file);
workbenchWindow.getShell().getDisplay().asyncExec(new Runnable()
{
public void run()
{
((ISetSelectionTarget)activePart).selectReveal(targetSelection);
}
});
}
try
{
workbenchPage.openEditor(new FileEditorInput(file), workbenchWindow.getWorkbench().getEditorRegistry().getDefaultEditor(file.getFullPath().toString(), Platform.getContentTypeManager().getContentType("org.eclipse.emf.ecore")).getId());
}
catch (PartInitException pie)
{
XcoreActivator.getInstance().getLog().log(new Status(IStatus.WARNING, "org.eclipse.emf.ecore.xcore.ui", 0, pie.getLocalizedMessage(), pie));
}
}
catch (IOException ioe)
{
XcoreActivator.getInstance().getLog().log(new Status(IStatus.WARNING, "org.eclipse.emf.ecore.xcore.ui", 0, ioe.getLocalizedMessage(), ioe));
}
}
finally
{
progressMonitor.done();
}
}
});
}
catch (InterruptedException ie)
{
// ignore
}
catch (InvocationTargetException ite)
{
XcoreActivator.getInstance().getLog().log(new Status(IStatus.WARNING, "org.eclipse.emf.ecore.xcore.ui", 0, ite.getLocalizedMessage(), ite));
}
}
/*
static class EcoreXcoreBuilder
{
List<Runnable> runnables = new ArrayList<Runnable>();
XPackage getXPackage(EPackage ePackage)
{
XPackage xPackage = XcoreFactory.eINSTANCE.createXPackage();
handleAnnotations(ePackage, xPackage);
String name = ePackage.getName();
xPackage.setName(name);
// TODO
// xPackage.setNsURI(ePackage.getNsURI());
// xPackage.setNsPrefix(ePackage.getNsPrefix());
for (EClassifier eClassifier : ePackage.getEClassifiers())
{
XClassifier xClassifier = getXClassifier(eClassifier);
xPackage.getClassifiers().add(xClassifier);
}
// Hook up local references.
//
for (Runnable runnable : runnables)
{
runnable.run();
}
runnables.clear();
return xPackage;
}
void handleAnnotations(final EModelElement eModelElement, final XModelElement xModelElement)
{
runnables.add
(new Runnable()
{
@Override
public void run()
{
for (EAnnotation eAnnotation : eModelElement.getEAnnotations())
{
XAnnotation xAnnotation = XcoreFactory.eINSTANCE.createXAnnotation();
String source = eAnnotation.getSource();
xAnnotation.setSource(getXAnnotationDirective(xModelElement, source));
for (Map.Entry<String, String> detail : eAnnotation.getDetails())
{
xAnnotation.getDetails().put(detail.getKey(), detail.getValue());
}
xModelElement.getAnnotations().add(xAnnotation);
}
}
});
}
XAnnotationDirective getXAnnotationDirective(XModelElement xModelElement, String source)
{
XPackage xPackage = (XPackage)EcoreUtil.getRootContainer(xModelElement);
for (XAnnotationDirective xAnnotationDirective : xPackage.getAnnotationDirectives())
{
if (source.equals(xAnnotationDirective.getSourceURI()))
{
return xAnnotationDirective;
}
}
XAnnotationDirective xAnnotationDirective = XcoreFactory.eINSTANCE.createXAnnotationDirective();
xAnnotationDirective.setSourceURI(source);
// TODO
URI sourceURI = URI.createURI(source);
xAnnotationDirective.setName(sourceURI.lastSegment());
xPackage.getAnnotationDirectives().add(xAnnotationDirective);
return xAnnotationDirective;
}
XClassifier getXClassifier(EClassifier eClassifier)
{
XClassifier xClassifier;
if (eClassifier instanceof EClass)
{
xClassifier = getXClass((EClass)eClassifier);
}
else if (eClassifier instanceof EEnum)
{
xClassifier = getXEnum((EEnum)eClassifier);
}
else
{
xClassifier = getXDataType((EDataType)eClassifier);
}
handleAnnotations(eClassifier, xClassifier);
xClassifier.setName(eClassifier.getName());
String instanceTypeName = eClassifier.getInstanceTypeName();
if (instanceTypeName != null)
{
xClassifier.setInstanceTypeName(instanceTypeName);
}
for (ETypeParameter eTypeParameter : eClassifier.getETypeParameters())
{
XTypeParameter xTypeParameter = getXTypeParameter(eTypeParameter);
xClassifier.getTypeParameters().add(xTypeParameter);
}
return xClassifier;
}
XClass getXClass(EClass eClass)
{
XClass xClass = XcoreFactory.eINSTANCE.createXClass();
if (eClass.isInterface())
{
xClass.setInterface(true);
}
else if (eClass.isAbstract())
{
xClass.setAbstract(true);
}
for (EGenericType eGenericSuperType : eClass.getEGenericSuperTypes())
{
xClass.getSuperTypes().add(getXGenericType(eGenericSuperType));
}
for (EStructuralFeature eStructuralFeature : eClass.getEStructuralFeatures())
{
XStructuralFeature xStructuralFeature = getXStructuralFeature(eStructuralFeature);
xClass.getMembers().add(xStructuralFeature);
}
for (EOperation eOperation : eClass.getEOperations())
{
XOperation xOperation = getXOperation(eOperation);
xClass.getMembers().add(xOperation);
}
return xClass;
}
XOperation getXOperation(EOperation eOperation)
{
XOperation xOperation = XcoreFactory.eINSTANCE.createXOperation();
handleXTypedElement(xOperation, eOperation);
for (EParameter eParameter : eOperation.getEParameters())
{
XParameter xParameter = getXParameter(eParameter);
xOperation.getParameters().add(xParameter);
}
for (ETypeParameter eTypeParameter : eOperation.getETypeParameters())
{
XTypeParameter xTypeParameter = getXTypeParameter(eTypeParameter);
xOperation.getTypeParameters().add(xTypeParameter);
}
for (EGenericType eException : eOperation.getEGenericExceptions())
{
XGenericType xException = getXGenericType(eException);
xOperation.getExceptions().add(xException);
}
EAnnotation ecoreAnnotation = eOperation.getEAnnotation(EcorePackage.eNS_URI);
if (ecoreAnnotation != null && !ecoreAnnotation.getContents().isEmpty())
{
EObject body = ecoreAnnotation.getContents().get(0);
if (body instanceof XBlockExpression)
{
xOperation.setBody((XBlockExpression)body);
}
}
return xOperation;
}
XParameter getXParameter(EParameter eParameter)
{
XParameter xParameter = XcoreFactory.eINSTANCE.createXParameter();
handleXTypedElement(xParameter, eParameter);
return xParameter;
}
XTypeParameter getXTypeParameter(ETypeParameter eTypeParameter)
{
XTypeParameter xTypeParameter = XcoreFactory.eINSTANCE.createXTypeParameter();
xTypeParameter.setName(eTypeParameter.getName());
for (EGenericType eGenericType : eTypeParameter.getEBounds())
{
xTypeParameter.getBounds().add(getXGenericType(eGenericType));
}
return xTypeParameter;
}
void handleXTypedElement(XTypedElement xTypedElement, ETypedElement eTypedElement)
{
handleAnnotations(eTypedElement, xTypedElement);
xTypedElement.setName(eTypedElement.getName());
xTypedElement.setType(getXGenericType(eTypedElement.getEGenericType()));
if (eTypedElement.isUnique() && !(eTypedElement instanceof EReference))
{
xTypedElement.setUnique(true);
}
if (!eTypedElement.isOrdered())
{
xTypedElement.setUnordered(true);
}
int lowerBound = eTypedElement.getLowerBound();
int upperBound = eTypedElement.getUpperBound();
if (lowerBound == 0)
{
if (upperBound == EStructuralFeature.UNBOUNDED_MULTIPLICITY)
{
xTypedElement.setMultiplicity(new int [] {});
}
else if (upperBound == 1)
{
xTypedElement.setMultiplicity(new int [] {-3});
}
else
{
xTypedElement.setMultiplicity(new int [] {0, upperBound});
}
}
else if (lowerBound == 1)
{
if (upperBound == EStructuralFeature.UNBOUNDED_MULTIPLICITY)
{
xTypedElement.setMultiplicity(new int [] {-2});
}
else if (lowerBound != 1)
{
xTypedElement.setMultiplicity(new int [] {1, upperBound});
}
}
else if (lowerBound == upperBound)
{
xTypedElement.setMultiplicity(new int [] {lowerBound});
}
else
{
xTypedElement.setMultiplicity(new int [] {lowerBound, upperBound});
}
}
XGenericType getXGenericType(EGenericType eGenericType)
{
final XGenericType xGenericType = XcoreFactory.eINSTANCE.createXGenericType();
EGenericType lowerBound = eGenericType.getELowerBound();
if (lowerBound != null)
{
xGenericType.setLowerBound(getXGenericType(lowerBound));
}
EGenericType upperBound = eGenericType.getEUpperBound();
if (upperBound != null)
{
xGenericType.setUpperBound(getXGenericType(upperBound));
}
for (EGenericType typeArgument : eGenericType.getETypeArguments())
{
xGenericType.getTypeArguments().add(getXGenericType(typeArgument));
}
EClassifier eClassifier = eGenericType.getEClassifier();
if (eClassifier != null)
{
xGenericType.setType(eClassifier);
}
else
{
xGenericType.setType(eGenericType.getETypeParameter());
}
return xGenericType;
}
XClassifier getClassifier(XPackage xPackage, String name)
{
for (XClassifier xClassifier : xPackage.getClassifiers())
{
if (name.equals(xClassifier.getName()))
{
return xClassifier;
}
}
return null;
}
XStructuralFeature getStructuralFeature(XClass xClass, String name)
{
for (XMember xMember : xClass.getMembers())
{
if (xMember instanceof XStructuralFeature && name.equals(xMember.getName()))
{
return (XStructuralFeature)xMember;
}
}
return null;
}
XStructuralFeature getXStructuralFeature(EStructuralFeature eStructuralFeature)
{
final XStructuralFeature xStructuralFeature = XcoreFactory.eINSTANCE.createXStructuralFeature();
if (eStructuralFeature instanceof EReference)
{
final EReference eReference = (EReference)eStructuralFeature;
if (eReference.isContainment())
{
xStructuralFeature.setContainment(true);
if (eReference.isResolveProxies())
{
xStructuralFeature.setResolveProxies(true);
}
}
else if (!eReference.isResolveProxies())
{
xStructuralFeature.setLocal(true);
}
EReference opposite = eReference.getEOpposite();
if (opposite != null)
{
xStructuralFeature.setOpposite(opposite);
}
xStructuralFeature.getKeys().addAll(eReference.getEKeys());
}
else
{
EAttribute eAttribute = (EAttribute)eStructuralFeature;
if (eAttribute.isID())
{
xStructuralFeature.setID(true);
}
}
if (!eStructuralFeature.isChangeable())
{
xStructuralFeature.setReadonly(true);
}
if (eStructuralFeature.isTransient())
{
xStructuralFeature.setTransient(true);
}
if (eStructuralFeature.isVolatile())
{
xStructuralFeature.setVolatile(true);
}
if (eStructuralFeature.isDerived())
{
xStructuralFeature.setDerived(true);
}
if (eStructuralFeature.isUnsettable())
{
xStructuralFeature.setUnsettable(true);
}
handleXTypedElement(xStructuralFeature, eStructuralFeature);
xStructuralFeature.setName(eStructuralFeature.getName());
return xStructuralFeature;
}
XDataType getXDataType(EDataType eDataType)
{
XDataType xDataType = XcoreFactory.eINSTANCE.createXDataType();
return xDataType;
}
XEnum getXEnum(EEnum eEnum)
{
XEnum xEnum = XcoreFactory.eINSTANCE.createXEnum();
for (EEnumLiteral eEnumLiteral : eEnum.getELiterals())
{
xEnum.getLiterals().add(getXEnumLiteral(eEnumLiteral));
}
return xEnum;
}
XEnumLiteral getXEnumLiteral(EEnumLiteral eEnumLiteral)
{
XEnumLiteral xEnumLiteral = XcoreFactory.eINSTANCE.createXEnumLiteral();
handleAnnotations(eEnumLiteral, xEnumLiteral);
xEnumLiteral.setName(eEnumLiteral.getName());
if (!eEnumLiteral.getName().equals(eEnumLiteral.getLiteral()))
{
xEnumLiteral.setLiteral(eEnumLiteral.getLiteral());
}
xEnumLiteral.setValue(eEnumLiteral.getValue());
return xEnumLiteral;
}
}
*/
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction,
* org.eclipse.jface.viewers.ISelection)
*/
@Override
public void selectionChanged(IAction action, ISelection selection)
{
action.setEnabled(IStructuredSelection.class.isInstance(selection) && getInputEPackage((IStructuredSelection)selection) != null);
}
}